<?php

require_once 'class.DbConnectionFestival.php';

/**
 * Description of EvtFactory
 *
 * @author sga
 */
class EvtFactory {

    private $dbConn;

    function __construct() {
        $this->dbConn = new DbConnectionFestival();
    }

    /**
     * Funzione che permette di ottenere un'array formattato al fine di contenere un albero di categorie e di famiglie di categorie
     * Struttura array categorie:
     * $arr[id_famiglia]["nomefam"]="nome famiglia"
     * $arr[id_famiglia]["elementi"][id_elemento]["nomecat"]="nome elemento"
     * $arr[id_famiglia]["elementi"][id_elemento]["descrizione"]="descrizione"
     * @return <Array> L'array formattato come sopra
     */
    function getTypesAndCategories() {

        $arr = $this->dbConn->executeQueryReturnArray("select t.id as idcat, t.nome as nomecat, t.descrizione as desccat, t.path_icona as icocat, ft.id as idfam, ft.nome as nomefam from tipologie t join famiglie_tipologie ft on t.famiglie_tipologie_id=ft.id");
        /**
         * Struttura array categorie:
         * $arr[id_famiglia]["nomefam"]="nome famiglia"
         * $arr[id_famiglia]["elementi"][id_elemento]["nomecat"]="nome elemento"
         * $arr[id_famiglia]["elementi"][id_elemento]["descrizione"]="descrizione"
         */
        foreach ($arr as $line) {
            $ret[$line['idfam']]['nomefam'] = $line['nomefam'];
            $ret[$line['idfam']]['idfam'] = $line['idfam'];
            $ret[$line['idfam']]['elementi'][$line['idcat']]['idcat'] = $line['idcat'];
            $ret[$line['idfam']]['elementi'][$line['idcat']]['idfam'] = $line['idfam'];
            $ret[$line['idfam']]['elementi'][$line['idcat']]['nomecat'] = $line['nomecat'];
            $ret[$line['idfam']]['elementi'][$line['idcat']]['desccat'] = $line['desccat'];
            $ret[$line['idfam']]['elementi'][$line['idcat']]['icocat'] = $line['icocat'];
        }
        return $ret;
    }

    /**
     * Crea un array associativo contenente a livello base gli id delle famiglie
     * e, all'indice di ogni id un array contenente gli identificativi delle
     * singole categorie.
     * @return array l'array associativo descritto 
     */
    function getCheckTypesAndCategories() {
        $rs = $this->dbConn->ExecuteQueryReturnResultset("select id as idcat, famiglie_tipologie_id as idfam from tipologie");
        while (!$rs->EOF) {
            //$arr[] = $rs->fields;
            $arr[$rs->fields['idfam']][$rs->fields['idcat']] = 0;
            $rs->MoveNext();
        }
        return $arr;
    }



    function getAllEventIds() {
        $query = "
            SELECT DISTINCT e.id FROM eventi e
                join eventi_has_tipologie ehti
                    on e.id=ehti.eventi_id
                join eventi_has_tempo ehte
                    on ehte.eventi_id=e.id
                join tempo t
                    on ehte.tempo_id=t.id ";
        return $this->dbConn->executeQueryReturnArray($query);
    }
    /**
     * metodo che permette di filtrare gli eventi restituendo in output
     * solo gli identificativi di quelli i cui dati corrispondono ai parametri
     * specificati all'interno delle variabili
     * @param <type> $categories le categorie di eventi
     * @param <type> $timeIntervals
     * @param <type> $namePart
     * @return <Array<int>> array contenente gli identificativi dei singoli
     * eventi restituiti dalla query
     */
    function getFilteredEventIds($categories=null, $timeIntervals=null, $namePart=null) {
        //compongo la query
        $query = "
            SELECT DISTINCT e.id FROM eventi e
                join eventi_has_tipologie ehti
                    on e.id=ehti.eventi_id
                join eventi_has_tempo ehte
                    on ehte.eventi_id=e.id
                join tempo t
                    on ehte.tempo_id=t.id ";
        //se c'è qualcosa
        if (!is_null($categories) || !is_null($timeIntervals) || !is_null($namePart)){
            $query.=" WHERE ";
        }
        else {
            return null;
        }
        //se ci sono le categorie
        if (!is_null($categories)) {
            //print_r($categories);
            $query.="(";
            $temNum = 1;
            foreach ($categories as $idfam => $fam) {
                foreach ($fam as $idcat => $cat) {
                    if ($cat == 1) {
                        $temNum = 0;
                        $query.=" ehti.tipologie_id=" . $idcat . " OR";
                        //se le cat non sono uniche invece si dovrebbe fare
                        //$query.=" (ehti.tipologie_id=".$idcat." AND " ehti.tipologie_id_famiglie_id_tipologie=".$idfam.") OR";;
                    }
                }
            }
            $query.=" $temNum)"; //per compensare l'ultimo or
        }
        /**
         * Struttura della parametrizzazione per la gestione del tempo:
         * $timeIntervals[0]['giorno']=stringa rappresentante una data sql con il giorno
         * $timeIntervals[0]['oraini']=stringa rappresentante una data sql con l'ora di inizio
         * $timeIntervals[0]['orafin']=stringa rappresentante una data sql con l'ora di fine
         * NOTA: l'a data 'ora di inizio è il momento dopo cui l'evento ha luogo, l'a data'ora di fine
         * è il momento prima del quale l'evento ha luogo. La coppia di date ha quindi lo scopo di
         * creare un intervallo.
         */
        if (!is_null($timeIntervals)) {
            foreach ($timeIntervals as $timearr) {
                $query.=" AND /*TI*/ (" . "tempo.data=" . $timearr['data'];
                if (!is_null($timearr['inizio']))
                    $query.="AND tempo.orainizio>" . $timearr['orainizio'];
                if (!is_null($timearr['fine']))
                    $query.="AND tempo.orafine<" . $timearr['orafine'];
            }
            $query.=" )";
        }
        /**
         * Struttura da parametrizzare per il nome: le varie stringhe sono
         * separate da spazi, per ogni spazio è fatto il like del nome.
         * in futuro è meglio prevedere una ricerca anche nella descrizione
         * e la possibilità di mettere in and le stringhe invece che in or.
         */
        if (!is_null($namePart)) {
            if (!is_null($timeIntervals))
                $query.=" AND (";
            else
                $query.=" (";
            $inizio = true;
            $names = split(" ", urldecode($namePart));
            foreach ($names as $name) {
                $query.="e.nome LIKE \"%" . $name . "%\"";
                if ($inizio == true and count($names) > 1)
                    $query.=" OR ";
                $inizio = false;
            }
            $query.=")";
        }
//        if(is_null($categories)&& is_null($timeIntervals)&& is_null($namePart)
//        $query.=" 1"; //esce where 1 che restituisce tutti i risultati
        return $this->dbConn->executeQueryReturnArray($query);
    }

    /**
     * Genera una rappresentazione degli eventi 
     * @param <array> $arrayIdEventi l'array contenente gli identificativi degli
     * eventi da restituire
     */
    function getEventRepresentation($arrayIdEventi) {
        if (!isset($arrayIdEventi))
            return;
        //questa è la rappresentazione della classe evento
        $query = "
            SELECT e.id as evt_id,
                e.nome as evt_nome,
                e.tempo_visita_consigliato_minuti as tvc,
                e.descrizione as evt_descrizione,
                l.id as id_luogo,
                l.nome as nome_luogo,
                l.lat as lat,
                l.lon as lon
            FROM eventi e
                join luoghi l
                    on l.id=e.luoghi_id";
        $first = true;
        foreach ($arrayIdEventi as $idEvento) {
            if ($first == true)
                $query.=" WHERE e.id=" . $idEvento['id'];
            else
                $query.=" OR e.id=" . $idEvento['id'];
            $first = false;
        }
        //print($query);
        $arr = $this->dbConn->executeQueryReturnArray($query);
        //ora ho i singoli eventi, rappresento le categorie
        $queryCat = "
            SELECT 
                fti.nome as fam_tip_nome,
                ti.nome as tip_nome,
                fti.id as famiglia_id,
                ti.id as categoria_id,
                ti.path_icona as path_icona
            FROM eventi e
                join eventi_has_tipologie ehti
                    on e.id=ehti.eventi_id
                join tipologie ti
                    on ti.id=ehti.tipologie_id
                join famiglie_tipologie fti
                    on fti.id=ti.famiglie_tipologie_id";

        $queryTempo = "
            SELECT
                t.data as data,
                t.orainizio as inizio,
                t.orafine as fine,
                t.tempo_visita_vincolante as vinc,
                t.id as id_tempo
            FROM eventi e
                join eventi_has_tempo ehte
                    on ehte.eventi_id=e.id
                join tempo t
                    on ehte.tempo_id=t.id";
        
        foreach ($arr as $evt) {

            $listaEventiDefinitiva[$evt['evt_id']]['id'] = $evt['evt_id'];
            $listaEventiDefinitiva[$evt['evt_id']]['nome'] = $evt['evt_nome'];
            $listaEventiDefinitiva[$evt['evt_id']]['descrizione'] = $evt['evt_descrizione'];
            $listaEventiDefinitiva[$evt['evt_id']]['tempo_visita_consigliato'] = $evt['tvc'];
            $listaEventiDefinitiva[$evt['evt_id']]['id_luogo'] = $evt['id_luogo'];
            $listaEventiDefinitiva[$evt['evt_id']]['nome_luogo'] = $evt['nome_luogo'];
            $listaEventiDefinitiva[$evt['evt_id']]['lat'] = $evt['lat'];
            $listaEventiDefinitiva[$evt['evt_id']]['lon'] = $evt['lon'];

//            print($queryCat." WHERE e.id=".$evt['evt_id']);
//            print($queryTempo." WHERE e.id=".$evt['evt_id']);

            $arrCat = $this->dbConn->executeQueryReturnArray($queryCat . " WHERE e.id=" . $evt['evt_id']);
            foreach ($arrCat as $categoria) {
                $listaEventiDefinitiva[$evt['evt_id']]['categorie'][] = array(
                    'categoria' => $categoria['tip_nome'],
                    'famiglia' => $categoria['fam_tip_nome'],
                    'categoria_id' => $categoria['categoria_id'],
                    'famiglia_id' => $categoria['famiglia_id'],
                    'path_icona' => $categoria['path_icona']
                    );

            }
            $arrTem = $this->dbConn->executeQueryReturnArray($queryTempo . " WHERE e.id=" . $evt['evt_id']);
            foreach ($arrTem as $orario) {
                //data inizio fine vinc
                $listaEventiDefinitiva[$evt['evt_id']]['orari'][] = array(
                    'data' => $orario['data'],
                    'inizio' => $orario['inizio'],
                    'fine' => $orario['fine'],
                    'vincolo' => $orario['vinc'],
                    'id_tempo'=>$orario['id_tempo']);
            }
//            print "\n\nEVENTOH ".$evt['evt_id']."\n"; print_r($arrCat);
//            print_r($arrTem);
        }
        return($listaEventiDefinitiva);
    }

    /**
     * Funzione che permette di creare una codifica degli eventi come oggetti
     * da inviare tramite il backend al client codificati in json.
     * @param <mixed> $rowEvt
     */
    function encodeEventList($arrEvt) {
        //un luogo, n tempi, un nome
        foreach ($arrEvt as $rowEvt) {
            if (isset($listaEventi[$rowEvt['eventi_id']])) {
                $listaEventi[$rowEvt['eventi_id']]['orari'][] =
                        array('data' => $rowEvt['data'],
                            'orainizio' => $rowEvt['orainizio'],
                            'orafine' => $rowEvt['orafine'],
                            'tempo_visita_vincolante' => $rowEvt['tempo_visita_vincolante']
                );
            } else {
                $listaEventi[$rowEvt['eventi_id']]['id_evento'] = $rowEvt['eventi_id'];
                $listaEventi[$rowEvt['eventi_id']]['nome_evento'] = $rowEvt['nome'];
                $listaEventi[$rowEvt['eventi_id']]['luogo'] = array($rowEvt['nome']);

                $listaEventi[$rowEvt['eventi_id']]['orari'][] =
                        array('data' => $rowEvt['data'],
                            'orainizio' => $rowEvt['orainizio'],
                            'orafine' => $rowEvt['orafine'],
                            'tempo_visita_vincolante' => $rowEvt['tempo_visita_vincolante']
                );
            }
        }
    }
}
?>
